using DeviceCommons.DeviceMessages.Builders;
using DeviceCommons.DeviceMessages.Factories;
using DeviceCommons.DeviceMessages.Enums;
using DeviceCommons.DeviceMessages.Serialization.V2.Parsers;
using DeviceCommons.DeviceMessages.Serialization;
using DeviceCommons.DataHandling;
using System.Text;

namespace ConsoleTestApp
{
    /// <summary>
    /// 快速解析演示程序
    /// 展示工厂模式在解析时的应用
    /// </summary>
    public class FastParsingDemo
    {
        public static void RunDemo()
        {
            Console.WriteLine("=== 快速解析工厂模式演示 ===\n");

            // 1. 注册设备类型的状态配置
            Console.WriteLine("1. 注册设备类型的状态配置...");
            RegisterDeviceConfigurations();

            // 2. 创建测试消息
            Console.WriteLine("2. 创建测试消息...");
            var testMessages = CreateTestMessages();

            // 3. 演示快速解析
            Console.WriteLine("3. 演示快速解析...");
            DemonstrateFastParsing(testMessages);

            // 4. 演示传统解析
            Console.WriteLine("4. 演示传统解析...");
            DemonstrateTraditionalParsing(testMessages);

            // 5. 性能对比
            Console.WriteLine("5. 性能对比...");
            PerformanceComparison(testMessages);

            // 6. 显示统计信息
            Console.WriteLine("6. 显示统计信息...");
            ShowStatistics();

            // 7. 演示偏移量计算
            Console.WriteLine("7. 演示偏移量计算...");
            DemonstrateOffsetCalculation();
        }

        /// <summary>
        /// 注册设备配置
        /// </summary>
        private static void RegisterDeviceConfigurations()
        {
            // 注册设备类型1：温度传感器
            DeviceStateConfigurationRegistry.RegisterConfiguration(1, builder =>
            {
                builder
                    .AddStringState(1, "设备名称", "设备的显示名称", true, "温度传感器")
                    .AddInt32State(2, "温度", "设备温度值", true, 25)
                    .AddBooleanState(3, "运行状态", "设备是否正在运行", true, false);
            });

            // 注册设备类型2：湿度传感器
            DeviceStateConfigurationRegistry.RegisterConfiguration(2, builder =>
            {
                builder
                    .AddStringState(1, "设备名称", "设备的显示名称", true, "湿度传感器")
                    .AddFloat32State(2, "湿度", "设备湿度值", true, 60.0f)
                    .AddBooleanState(3, "运行状态", "设备是否正在运行", true, false)
                    .AddInt32State(4, "电池电量", "设备电池电量", false, 100);
            });

            // 注册设备类型3：压力传感器
            DeviceStateConfigurationRegistry.RegisterConfiguration(3, builder =>
            {
                builder
                    .AddStringState(1, "设备名称", "设备的显示名称", true, "压力传感器")
                    .AddNumericState(2, "压力", "设备压力值", true, 1013.25)
                    .AddUInt16State(3, "海拔", "设备海拔高度", false, 0);
            });

            Console.WriteLine($"已注册 {DeviceStateConfigurationRegistry.GetRegisteredDeviceTypes().Count()} 个设备类型");
        }

        /// <summary>
        /// 创建测试消息
        /// </summary>
        /// <returns>测试消息集合</returns>
        private static List<(string hexString, byte deviceType, string description)> CreateTestMessages()
        {
            var messages = new List<(string hexString, byte deviceType, string description)>();

            // 创建设备类型1的消息
            var message1 = DeviceMessageBuilder.Create()
                .WithHeader(version: 0x02, crcType: CRCTypeEnum.CRC16)
                .WithMainDevice("TempSensor", 1)
                .AddReading(0, reading =>
                {
                    reading.AddState(1, "温度传感器", StateValueTypeEnum.String);
                    reading.AddState(2, 28, StateValueTypeEnum.Int32);
                    reading.AddState(3, true, StateValueTypeEnum.Bool);
                })
                .BuildHex();

            messages.Add((message1, 1, "温度传感器消息"));

            // 创建设备类型2的消息
            var message2 = DeviceMessageBuilder.Create()
                .WithHeader(version: 0x02, crcType: CRCTypeEnum.CRC16)
                .WithMainDevice("HumiditySensor", 2)
                .AddReading(0, reading =>
                {
                    reading.AddState(1, "湿度传感器", StateValueTypeEnum.String);
                    reading.AddState(2, 65.5f, StateValueTypeEnum.Float32);
                    reading.AddState(3, true, StateValueTypeEnum.Bool);
                    reading.AddState(4, 85, StateValueTypeEnum.Int32);
                })
                .BuildHex();

            messages.Add((message2, 2, "湿度传感器消息"));

            // 创建设备类型3的消息
            var message3 = DeviceMessageBuilder.Create()
                .WithHeader(version: 0x02, crcType: CRCTypeEnum.CRC16)
                .WithMainDevice("PressureSensor", 3)
                .AddReading(0, reading =>
                {
                    reading.AddState(1, "压力传感器", StateValueTypeEnum.String);
                    reading.AddState(2, 1015.8d, StateValueTypeEnum.Double);
                    reading.AddState(3, (ushort)150, StateValueTypeEnum.UInt16);
                })
                .BuildHex();

            messages.Add((message3, 3, "压力传感器消息"));

            // 创建未注册设备类型的消息
            var message4 = DeviceMessageBuilder.Create()
                .WithHeader(version: 0x02, crcType: CRCTypeEnum.CRC16)
                .WithMainDevice("UnknownDevice", 99)
                .AddReading(0, reading =>
                {
                    reading.AddState(1, "未知设备", StateValueTypeEnum.String);
                    reading.AddState(2, "未知值", StateValueTypeEnum.String);
                })
                .BuildHex();

            messages.Add((message4, 99, "未注册设备类型消息"));

            Console.WriteLine($"创建了 {messages.Count} 个测试消息");
            return messages;
        }

        /// <summary>
        /// 演示快速解析
        /// </summary>
        /// <param name="testMessages">测试消息集合</param>
        private static void DemonstrateFastParsing(List<(string hexString, byte deviceType, string description)> testMessages)
        {
            Console.WriteLine("\n--- 快速解析演示 ---");
            
            var fastFactory = new FastReadingStateFactory();

            foreach (var (hexString, deviceType, description) in testMessages)
            {
                Console.WriteLine($"\n解析: {description}");
                Console.WriteLine($"设备类型: {deviceType}");
                Console.WriteLine($"支持快速解析: {fastFactory.SupportsFastParsing(deviceType)}");

                if (fastFactory.SupportsFastParsing(deviceType))
                {
                    try
                    {
                        // 模拟状态数据字节数组（实际应该从消息中提取）
                        var stateDataBytes = CreateMockStateData(deviceType);
                        var states = fastFactory.ParseReadingStates(stateDataBytes, deviceType);
                        
                        Console.WriteLine($"状态数量: {states.StateArray?.Length ?? 0}");
                        if (states.StateArray != null)
                        {
                            foreach (var state in states.StateArray)
                            {
                                Console.WriteLine($"  状态ID: {state.SID}, 值: {state.ValueText}, 类型: {state.ValueType}, 数据长度: {state.DataLength}");
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"快速解析失败: {ex.Message}");
                    }
                }
                else
                {
                    Console.WriteLine("该设备类型不支持快速解析");
                }
            }
        }

        /// <summary>
        /// 演示传统解析
        /// </summary>
        /// <param name="testMessages">测试消息集合</param>
        private static void DemonstrateTraditionalParsing(List<(string hexString, byte deviceType, string description)> testMessages)
        {
            Console.WriteLine("\n--- 传统解析演示 ---");
            
            var defaultParser = DeviceMessageSerializerProvider.MessagePar;

            foreach (var (hexString, deviceType, description) in testMessages)
            {
                Console.WriteLine($"\n解析: {description}");
                Console.WriteLine($"设备类型: {deviceType}");

                try
                {
                    // 创建禁用快速解析的上下文
                    var context = ParsingContext.Create(deviceType);
                    context.EnableFastParsing = false;
                    
                    // 设置解析上下文
                    if (defaultParser is IContextAwareParser contextAwareParser)
                    {
                        contextAwareParser.SetContext(context);
                    }
                    
                    var message = defaultParser.Parser(hexString);
                    
                    if (message?.MainDevice != null)
                    {
                        Console.WriteLine($"设备ID: {message.MainDevice.DID}");
                        Console.WriteLine($"设备类型: {message.MainDevice.DeviceType}");
                        Console.WriteLine($"读数数量: {message.MainDevice.Reading?.ReadingArray?.Length ?? 0}");

                        if (message.MainDevice.Reading?.ReadingArray != null)
                        {
                            foreach (var reading in message.MainDevice.Reading.ReadingArray)
                            {
                                Console.WriteLine($"  时间偏移: {reading.TimeOffset}");
                                Console.WriteLine($"  状态数量: {reading.State?.StateArray?.Length ?? 0}");

                                if (reading.State?.StateArray != null)
                                {
                                    foreach (var state in reading.State.StateArray)
                                    {
                                        Console.WriteLine($"    状态ID: {state.SID}, 值: {state.ValueText}, 类型: {state.ValueType}");
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"解析失败: {ex.Message}");
                }
            }
        }

        /// <summary>
        /// 性能对比
        /// </summary>
        /// <param name="testMessages">测试消息集合</param>
        private static void PerformanceComparison(List<(string hexString, byte deviceType, string description)> testMessages)
        {
            Console.WriteLine("\n--- 性能对比 ---");
            
            var fastFactory = new FastReadingStateFactory();
            var defaultParser = DeviceMessageSerializerProvider.MessagePar;

            const int iterations = 1000;
            var stopwatch = System.Diagnostics.Stopwatch.StartNew();

            // 测试快速解析性能
            Console.WriteLine($"\n快速解析性能测试 ({iterations} 次迭代):");
            
            foreach (var (hexString, deviceType, description) in testMessages.Where(m => fastFactory.SupportsFastParsing(m.deviceType)))
            {
                var stateDataBytes = CreateMockStateData(deviceType);
                
                stopwatch.Restart();
                for (int i = 0; i < iterations; i++)
                {
                    try
                    {
                        fastFactory.ParseReadingStates(stateDataBytes, deviceType);
                    }
                    catch { /* 忽略错误 */ }
                }
                stopwatch.Stop();
                
                Console.WriteLine($"  {description}: {stopwatch.ElapsedMilliseconds}ms (平均: {stopwatch.ElapsedMilliseconds / (double)iterations:F3}ms)");
            }

            // 测试传统解析性能
            Console.WriteLine($"\n传统解析性能测试 ({iterations} 次迭代):");
            
            foreach (var (hexString, deviceType, description) in testMessages)
            {
                stopwatch.Restart();
                for (int i = 0; i < iterations; i++)
                {
                    try
                    {
                        defaultParser.Parser(hexString);
                    }
                    catch { /* 忽略错误 */ }
                }
                stopwatch.Stop();
                
                Console.WriteLine($"  {description}: {stopwatch.ElapsedMilliseconds}ms (平均: {stopwatch.ElapsedMilliseconds / (double)iterations:F3}ms)");
            }
        }

        /// <summary>
        /// 显示统计信息
        /// </summary>
        private static void ShowStatistics()
        {
            Console.WriteLine("\n--- 统计信息 ---");
            
            var fastFactory = new FastReadingStateFactory();

            Console.WriteLine($"支持快速解析的设备类型数: {DeviceStateConfigurationRegistry.GetRegisteredDeviceTypes().Count()}");

            Console.WriteLine("\n支持快速解析的设备类型:");
            foreach (var deviceType in DeviceStateConfigurationRegistry.GetRegisteredDeviceTypes())
            {
                var config = fastFactory.SupportsFastParsing(deviceType);
                Console.WriteLine($"  设备类型 {deviceType}: {(config ? "支持" : "不支持")}");
            }

            // 显示注册中心统计信息
            var (totalDeviceTypes, totalStates) = DeviceStateConfigurationRegistry.GetStatistics();
            Console.WriteLine($"\n注册中心统计:");
            Console.WriteLine($"  已注册配置数: {totalDeviceTypes}");
            Console.WriteLine($"  已注册工厂数: {totalStates}");
        }

        /// <summary>
        /// 演示偏移量计算
        /// </summary>
        private static void DemonstrateOffsetCalculation()
        {
            Console.WriteLine("\n--- 偏移量计算演示 ---");
            
            var fastFactory = new FastReadingStateFactory();
            
            // 获取设备类型1的配置
            var config = DeviceStateConfigurationRegistry.GetConfiguration(1);
            if (config != null)
            {
                Console.WriteLine($"设备类型1的状态配置:");
                foreach (var stateDef in config.StateDefinitions)
                {
                    var typeSize = GetTypeSize(stateDef.ValueType);
                    Console.WriteLine($"  状态ID {stateDef.Sid}: {stateDef.Name} ({stateDef.ValueType}) - 字节大小: {typeSize}");
                }
                
                var totalBytes = fastFactory.CalculateStateDataLength(1);
                Console.WriteLine($"总字节长度: {totalBytes}");
            }

            // 获取设备类型2的配置
            config = DeviceStateConfigurationRegistry.GetConfiguration(2);
            if (config != null)
            {
                Console.WriteLine($"\n设备类型2的状态配置:");
                foreach (var stateDef in config.StateDefinitions)
                {
                    var typeSize = GetTypeSize(stateDef.ValueType);
                    Console.WriteLine($"  状态ID {stateDef.Sid}: {stateDef.Name} ({stateDef.ValueType}) - 字节大小: {typeSize}");
                }
                
                var totalBytes = fastFactory.CalculateStateDataLength(2);
                Console.WriteLine($"总字节长度: {totalBytes}");
            }
        }

        /// <summary>
        /// 创建模拟状态数据
        /// </summary>
        /// <param name="deviceType">设备类型</param>
        /// <returns>模拟的状态数据字节数组</returns>
        private static ReadOnlySpan<byte> CreateMockStateData(byte deviceType)
        {
            var bytes = new List<byte>();
            
            switch (deviceType)
            {
                case 1: // 温度传感器
                    bytes.Add(3); // 状态数量 = 3
                    
                    // 状态1: SID(1) + 类型(1) + 长度(1) + 字符串值
                    bytes.Add(1); // SID = 1
                    bytes.Add((byte)StateValueTypeEnum.String); // 类型 = String
                    var tempSensorStr = "温度传感器";
                    var tempSensorBytes = Encoding.UTF8.GetBytes(tempSensorStr);
                    bytes.Add((byte)tempSensorBytes.Length); // 长度(1字节)
                    bytes.AddRange(tempSensorBytes); // 字符串内容
                    
                    // 状态2: SID(1) + 类型(1) + Int32值 (固定长度，无长度字段)
                    bytes.Add(2); // SID = 2
                    bytes.Add((byte)StateValueTypeEnum.Int32); // 类型 = Int32
                    bytes.AddRange(BitConverter.GetBytes(28)); // Int32值
                    
                    // 状态3: SID(1) + 类型(1) + Bool值 (固定长度，无长度字段)
                    bytes.Add(3); // SID = 3
                    bytes.Add((byte)StateValueTypeEnum.Bool); // 类型 = Bool
                    bytes.Add(1); // Bool值
                    break;
                    
                case 2: // 湿度传感器
                    bytes.Add(4); // 状态数量 = 4
                    
                    // 状态1: SID(1) + 类型(1) + 长度(1) + 字符串值
                    bytes.Add(1); // SID = 1
                    bytes.Add((byte)StateValueTypeEnum.String); // 类型 = String
                    var humiditySensorStr = "湿度传感器";
                    var humiditySensorBytes = Encoding.UTF8.GetBytes(humiditySensorStr);
                    bytes.Add((byte)humiditySensorBytes.Length); // 长度(1字节)
                    bytes.AddRange(humiditySensorBytes); // 字符串内容
                    
                    // 状态2: SID(1) + 类型(1) + Float32值 (固定长度，无长度字段)
                    bytes.Add(2); // SID = 2
                    bytes.Add((byte)StateValueTypeEnum.Float32); // 类型 = Float32
                    bytes.AddRange(BitConverter.GetBytes(65.5f)); // Float32值
                    
                    // 状态3: SID(1) + 类型(1) + Bool值 (固定长度，无长度字段)
                    bytes.Add(3); // SID = 3
                    bytes.Add((byte)StateValueTypeEnum.Bool); // 类型 = Bool
                    bytes.Add(1); // Bool值
                    
                    // 状态4: SID(1) + 类型(1) + Int32值 (固定长度，无长度字段)
                    bytes.Add(4); // SID = 4
                    bytes.Add((byte)StateValueTypeEnum.Int32); // 类型 = Int32
                    bytes.AddRange(BitConverter.GetBytes(85)); // Int32值
                    break;
                    
                case 3: // 压力传感器
                    bytes.Add(3); // 状态数量 = 3
                    
                    // 状态1: SID(1) + 类型(1) + 长度(1) + 字符串值
                    bytes.Add(1); // SID = 1
                    bytes.Add((byte)StateValueTypeEnum.String); // 类型 = String
                    var pressureSensorStr = "压力传感器";
                    var pressureSensorBytes = Encoding.UTF8.GetBytes(pressureSensorStr);
                    bytes.Add((byte)pressureSensorBytes.Length); // 长度(1字节)
                    bytes.AddRange(pressureSensorBytes); // 字符串内容
                    
                    // 状态2: SID(1) + 类型(1) + Double值 (固定长度，无长度字段)
                    bytes.Add(2); // SID = 2
                    bytes.Add((byte)StateValueTypeEnum.Double); // 类型 = Double
                    bytes.AddRange(BitConverter.GetBytes(1015.8)); // Double值
                    
                    // 状态3: SID(1) + 类型(1) + UInt16值 (固定长度，无长度字段)
                    bytes.Add(3); // SID = 3
                    bytes.Add((byte)StateValueTypeEnum.UInt16); // 类型 = UInt16
                    bytes.AddRange(BitConverter.GetBytes((ushort)150)); // UInt16值
                    break;
                    
                default:
                    bytes.Add(2); // 状态数量 = 2
                    
                    // 状态1: SID(1) + 类型(1) + 长度(1) + 字符串值
                    bytes.Add(1); // SID = 1
                    bytes.Add((byte)StateValueTypeEnum.String); // 类型 = String
                    var unknownStr = "未知设备";
                    var unknownBytes = Encoding.UTF8.GetBytes(unknownStr);
                    bytes.Add((byte)unknownBytes.Length); // 长度(1字节)
                    bytes.AddRange(unknownBytes); // 字符串内容
                    
                    // 状态2: SID(1) + 类型(1) + 长度(1) + 字符串值
                    bytes.Add(2); // SID = 2
                    bytes.Add((byte)StateValueTypeEnum.String); // 类型 = String
                    var unknownValueStr = "未知值";
                    var unknownValueBytes = Encoding.UTF8.GetBytes(unknownValueStr);
                    bytes.Add((byte)unknownValueBytes.Length); // 长度(1字节)
                    bytes.AddRange(unknownValueBytes); // 字符串内容
                    break;
            }
            
            return bytes.ToArray();
        }

        /// <summary>
        /// 获取类型的字节大小
        /// </summary>
        /// <param name="valueType">值类型</param>
        /// <returns>字节大小</returns>
        private static int GetTypeSize(StateValueTypeEnum valueType)
        {
            return valueType switch
            {
                StateValueTypeEnum.String => 1,      // 1字节长度前缀
                StateValueTypeEnum.Int32 => 4,
                StateValueTypeEnum.Int16 => 2,
                StateValueTypeEnum.UInt16 => 2,
                StateValueTypeEnum.Float32 => 4,
                StateValueTypeEnum.Double => 8,
                StateValueTypeEnum.Bool => 1,
                StateValueTypeEnum.Binary => 4,      // 4字节长度前缀
                StateValueTypeEnum.Timestamp => 8,
                _ => 0
            };
        }
    }
}
